import java.util.ArrayList;
import org.newdawn.slick.*;
import org.newdawn.slick.util.FontUtils;

/**
 * Handles the SettingsMenu
 * 
 * @author Gerrit Jamerson, CodeMonkeys
 * @version 4/5/13
 */
public class SettingsMenu extends MenuBase
{
    //commonResolution[aspectRatio][ID]
    private ArrayList[] commonResolutions;
    private String[] aspectRatios;

    private Vector2I Offset;
    private int intMaxSelection;
    private int controlMapMenuID;
    private int intBGMVol;
    private int intSFXVol;
    private int intResX;
    private int intResY;
    private int curSelection;
    private int curAspectSelection;
    private int curResolutionSelection;
    private boolean isFullscreen;
    /**
     * Constructs the Settings menu
     */
    public SettingsMenu()
    {
        Offset = new Vector2I(0,0);
        Offset.x = Settings.getResolutionX() / 2;
        Offset.y = Settings.getResolutionY() / 2;
        
        curSelection = 0;
        curAspectSelection = 0;
        curResolutionSelection = 0;

        intBGMVol = Settings.getBGMVolume();
        intSFXVol = Settings.getSFXVolume();
        isFullscreen = Settings.getFullscreen();
        intMaxSelection = 8;

        aspectRatios = new String[7];
        commonResolutions = new ArrayList[7];

        ArrayList<Vector2I> res = new ArrayList<Vector2I>();
        aspectRatios[0] = "3:2";
        res.add(new Vector2I(720, 480));
        res.add(new Vector2I(1152, 768));
        res.add(new Vector2I(1280, 854));
        res.add(new Vector2I(1440, 960));
        res.add(new Vector2I(2880, 1920));
        commonResolutions[0] = (ArrayList)res.clone();
        res.clear();

        aspectRatios[1] = "4:3";
        res.add(new Vector2I(320, 240));
        res.add(new Vector2I(640, 480));
        res.add(new Vector2I(800, 600));
        res.add(new Vector2I(1024, 768));
        res.add(new Vector2I(1152, 864));
        res.add(new Vector2I(1280, 960));
        res.add(new Vector2I(1400, 1050));
        res.add(new Vector2I(1600, 1200));
        res.add(new Vector2I(2048, 1536));
        res.add(new Vector2I(3200, 2400));
        res.add(new Vector2I(4000, 3000));
        res.add(new Vector2I(6400, 4800));
        commonResolutions[1] = (ArrayList)res.clone();
        res.clear();

        aspectRatios[2] = "5:3";        
        res.add(new Vector2I(800, 480));
        res.add(new Vector2I(1280, 768));
        commonResolutions[2] = (ArrayList)res.clone();
        res.clear();

        aspectRatios[3] = "5:4";
        res.add(new Vector2I(1280, 1024));
        res.add(new Vector2I(2560, 2048));
        res.add(new Vector2I(5120, 4096));
        commonResolutions[3] = (ArrayList)res.clone();
        res.clear();

        aspectRatios[4] = "16:9";
        res.add(new Vector2I(852, 480));
        res.add(new Vector2I(1280, 720));
        res.add(new Vector2I(1365, 768));
        res.add(new Vector2I(1600, 900));
        res.add(new Vector2I(1920, 1080));
        commonResolutions[4] = (ArrayList)res.clone();
        res.clear();

        aspectRatios[5] = "16:10";
        res.add(new Vector2I(320, 200));
        res.add(new Vector2I(640, 400));
        res.add(new Vector2I(1280, 800));
        res.add(new Vector2I(1440, 900));
        res.add(new Vector2I(1680, 1050));
        res.add(new Vector2I(1920, 1200));
        res.add(new Vector2I(2560, 1600));
        res.add(new Vector2I(3840, 2400));
        res.add(new Vector2I(7680, 4800));
        commonResolutions[5] = (ArrayList)res.clone();
        res.clear();

        aspectRatios[6] = "17:9";
        res.add(new Vector2I(2048, 1080));
        commonResolutions[6] = (ArrayList)res.clone();
        res.clear();

        for(int i = 0; i < aspectRatios.length; i++)
        {
            for(int o = 0; o < commonResolutions[i].size(); o++)
            {
                if(Settings.getResolutionX() == ((Vector2I)commonResolutions[i].get(o)).x)
                {
                    if(Settings.getResolutionY() == ((Vector2I)commonResolutions[i].get(o)).y)
                    {
                        curAspectSelection = i;
                        curResolutionSelection = o;
                    } //End if
                } //End if
            } //End nested for loop
        } //End for loop

        intResX = ((Vector2I)commonResolutions[curAspectSelection].get(curResolutionSelection)).x;
        intResY = ((Vector2I)commonResolutions[curAspectSelection].get(curResolutionSelection)).y;
        controlMapMenuID = MainMenuController.registerMenu(new ControlMapMenu());
    } //End constructor

    /**
     * Renders the menu on the screen.
     * 
     * @pre None
     * @param gameContainer The game container
     * @param graphics The graphics class
     * @return void
     * @post None
     */
    public void render(GameContainer gameContainer, Graphics graphics)
    {
        TrueTypeFont ttf = GameRegistry.getFont("fntMain");
        FontUtils.drawCenter(ttf, "Settings", Offset.x, Offset.y - 260, 0, Color.white);

        String[] prefix = new String[intMaxSelection];
        String[] suffix = new String[intMaxSelection];

        for(int i = 0; i < intMaxSelection; i++)
        {
            prefix[i] = "";
            suffix[i] = "";

            if(i == curSelection)
            {
                prefix[i] = "[ ";
                suffix[i] = " ]";
            } //End if
        } //End for loop

        FontUtils.drawCenter(ttf, prefix[0] + "Control Settings" + suffix[0], Offset.x, Offset.y - 160, 0, Color.white);
        FontUtils.drawCenter(ttf, prefix[1] + "BGM Volume " + intBGMVol + "%" + suffix[1], Offset.x, Offset.y - 100, 0, Color.white);
        FontUtils.drawCenter(ttf, prefix[2] + "SFX Volume " + intSFXVol + "%" + suffix[2], Offset.x, Offset.y - 60, 0, Color.white);
        FontUtils.drawCenter(ttf, prefix[3] + "Aspect Ratio " + aspectRatios[curAspectSelection] + suffix[3], Offset.x, Offset.y, 0, Color.white);
        FontUtils.drawCenter(ttf, prefix[4] + "Resolution " + intResX + "x" + intResY + suffix[4], Offset.x, Offset.y + 40, 0, Color.white);
        FontUtils.drawCenter(ttf, prefix[5] + "Fullscreen: " + isFullscreen + suffix[5], Offset.x, Offset.y + 80, 0, Color.white);
        FontUtils.drawCenter(ttf, prefix[6] + "Apply" + suffix[6], Offset.x, Offset.y + 140, 0, Color.white);
        FontUtils.drawCenter(ttf, prefix[7] + "Back" + suffix[7], Offset.x, Offset.y + 180, 0, Color.white);
    } //End render method

    /**
     * Renders the menu on the screen.
     * 
     * @pre None
     * @param gameContainer The game container
     * @param graphics The graphics class
     * @return void
     * @post None
     */
    public void update(GameContainer gameContainer, int intDelta)
    {
        Offset.x = Settings.getResolutionX() / 2;
        Offset.y = Settings.getResolutionY() / 2;
    } // End update method

    /**
     * A command has been pressed when this is called.
     * 
     * @pre None
     * @param command The command that was pressed.
     * @return void
     * @post None
     */
    public void controlPressed(Keys command)
    {
        switch(command)
        {
            case UP:
            curSelection--;
            break;

            case DOWN:
            curSelection++;
            break;

            case SELECT:
            switch(curSelection)
            {
                case  0:
                MainMenuController.setMenu(controlMapMenuID);
                break;

                case 6:
                try
                {
                    Settings.setResolutionX(intResX);
                    Settings.setResolutionY(intResY);
                    Settings.setBGMVolume(intBGMVol);
                    Settings.setSFXVolume(intSFXVol);
                    GameController.getGameContainer().setDisplayMode(intResX, intResY, isFullscreen);
                } //End try
                catch (SlickException e)
                {
                    System.out.println(e.getMessage());
                } //End catch
                break;

                case 7:
                MainMenuController.previousMenu();
                break;
            } //End switch
            break;

            case LEFT:
            switch(curSelection)
            {
                case 1:
                intBGMVol -= 10;
                break;

                case 2:
                intSFXVol -= 10;
                break;

                case 3:
                curAspectSelection -= 1;
                break;

                case 4:
                curResolutionSelection -= 1;
                break;

                case 5:
                isFullscreen = !isFullscreen;
                break;
            } //End switch
            break;

            case RIGHT:
            switch(curSelection)
            {
                case 1:
                intBGMVol += 10;
                break;

                case 2:
                intSFXVol += 10;
                break;

                case 3:
                curAspectSelection += 1;
                break;

                case 4:
                curResolutionSelection += 1;
                break;

                case 5:
                isFullscreen = !isFullscreen;
                break;
            } //End switch
            break;

            case BACK:
            MainMenuController.previousMenu();
            break;
        } //End switch

        intBGMVol = Math.max(Math.min(intBGMVol, 150), 0);
        intSFXVol = Math.max(Math.min(intSFXVol, 150), 0);
        curAspectSelection = Math.max(Math.min(curAspectSelection, aspectRatios.length - 1), 0);
        curResolutionSelection = Math.max(Math.min(curResolutionSelection, commonResolutions[curAspectSelection].size() - 1), 0);
        curSelection = Math.max(Math.min(curSelection, intMaxSelection - 1), 0);

        intResX = ((Vector2I)commonResolutions[curAspectSelection].get(curResolutionSelection)).x;
        intResY = ((Vector2I)commonResolutions[curAspectSelection].get(curResolutionSelection)).y;
    } //End command method

    /**
     * Called when the menu has been set as the current menu.
     * 
     * @pre None
     * @param None
     * @return Void
     * @post None
     */
    public void onSet()
    {

    } //End onSet method

    /**
     * Called when the menu has been unset.
     * 
     * @pre None
     * @param None
     * @return Void
     * @post None
     */
    public void onUnset()
    {
        Settings.setResolutionX(intResX);
        Settings.setResolutionY(intResY);
        Settings.setBGMVolume(intBGMVol);
        Settings.setSFXVolume(intSFXVol);
        Settings.setFullscreen(isFullscreen);
        Settings.saveSettings();
        removeFromRenderList();
    } //End onUnset method
} //End class
